package cn.itcast.account.service.impl;

import cn.itcast.account.entity.AccountFreeze;
import cn.itcast.account.mapper.AccountFreezeMapper;
import cn.itcast.account.mapper.AccountMapper;
import cn.itcast.account.service.AccountTccService;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class AccountTCCServiceImpl implements AccountTccService {


    @Autowired(required = false)
    private AccountMapper accountMapper;

    @Autowired(required = false)
    private AccountFreezeMapper accountFreezeMapper;


    /**
     * try
     * @param userId
     * @param money
     */
    @Override
    public void deduct(String userId, int money) {
        //1.获取事务id
        String xid = RootContext.getXID();

        //拒绝业务悬挂,就是在try之前不能有cancel的操作,
        AccountFreeze freeze = accountFreezeMapper.selectById(xid);
        if(freeze != null){
            return;
        }


        //2.扣减可用余额
        accountMapper.deduct(userId, money);
        //3.添加冻结金额记录
        AccountFreeze accountFreeze = new AccountFreeze();
        accountFreeze.setXid(xid);
        accountFreeze.setUserId(userId);
        accountFreeze.setFreezeMoney(money);
        accountFreeze.setState(AccountFreeze.State.TRY);

        accountFreezeMapper.insert(accountFreeze);
    }

    /**
     * confirm
     * @param context
     * @return
     */
    @Override
    @Transactional
    public boolean confirm(BusinessActionContext context) {

        //1.根据事务id删除冻结金额记录

        int count = accountFreezeMapper.deleteById(context.getXid());
        return count == 1 ;
    }

    @Override
    public boolean cancel(BusinessActionContext context) {

        //1.增加可用金额

        AccountFreeze freeze = accountFreezeMapper.selectById(context.getXid());

        //这里要做空回滚的判断,判断freeze是否为null
        String userId = context.getActionContext("userId").toString();

        if(freeze == null){
            freeze = new AccountFreeze();
            freeze.setXid(context.getXid());
            freeze.setUserId(userId);
            freeze.setFreezeMoney(0);
            freeze.setState(AccountFreeze.State.CANCEL);
        }

        //这步做幂等判断

        if(freeze.getState() == AccountFreeze.State.CONFIRM){
            return true;
        }

        accountMapper.refund(freeze.getUserId(),freeze.getFreezeMoney());


        freeze.setFreezeMoney(0);
        freeze.setState(AccountFreeze.State.CANCEL);

        //2.修改状态

        int count = accountFreezeMapper.updateById(freeze);

        return count == 1;
    }
}
